<template>
  <view class="out-bg">
    <!-- 筛选栏 -->
    <view class="top-bar">
      <view
        v-for="(tab, i) in statusTabs"
        :key="tab.value"
        class="tab-btn"
        :class="{ active: filterStatus === tab.value }"
        @click="setFilter(tab.value)"
        >{{ tab.label }}</view
      >
    </view>
    <!-- 查询栏 -->
    <view class="search-row">
      <input
        v-model.trim="searchText"
        class="search-input"
        placeholder="输入客户姓名查询"
      />
      <button class="search-btn" @click="search">查询</button>
      <button class="add-btn" @click="showAddDialog = true">+ 新建申请</button>
    </view>
    <!-- 外出申请列表 -->
    <view class="apply-list">
      <view class="apply-item" v-for="item in filteredList" :key="item.leaveId">
        <view class="info-row">
          <text class="client-name">{{ item.clientName }}</text>
          <view
            class="status-badge"
            :class="{
              pending: item.approvalStatus === '待审核',
              approved: item.approvalStatus === '通过',
              rejected: item.approvalStatus === '不通过',
            }"
          >
            {{ approvalText(item.approvalStatus) }}
          </view>
        </view>
        <view class="desc-row">外出事由：{{ item.reason }}</view>
        <view class="desc-row">外出时间：{{ item.outTime }}</view>
        <view class="desc-row">预计回院：{{ item.expectedReturnTime }}</view>
        <view class="desc-row" v-if="item.realReturnTime">
          实际回院：<text class="returned">{{ item.realReturnTime }}</text>
        </view>
        <view class="row-btns">
          <!-- 待审核 -->
          <button
            v-if="!item.realReturnTime && item.approvalStatus === '待审核'"
            class="row-btn-disabled"
            disabled
            style="flex: 1"
          >
            等待审核
          </button>
          <!-- 通过且未回归 -->
          <template
            v-else-if="!item.realReturnTime && item.approvalStatus === '通过'"
          >
            <button
              class="return-btn normal-btn"
              @click="openReturnDialog(item)"
              style="flex: 1"
            >
              登记回院
            </button>
            <button
              class="return-btn quick-btn"
              @click="quickReturn(item)"
              style="flex: 1"
            >
              立即回归
            </button>
          </template>
        </view>
      </view>
      <view v-if="!filteredList.length && !loading" class="empty-tip"
        >暂无数据</view
      >
      <view v-if="loading" class="empty-tip">加载中...</view>
      <view v-if="!hasMore && filteredList.length" class="empty-tip"
        >没有更多了</view
      >
    </view>
    <!-- 新建外出申请弹窗 -->
    <view v-if="showAddDialog" class="mask">
      <view class="dialog dialog-beauty">
        <view class="dialog-title">新建外出申请</view>
        <view class="dialog-form">
          <view class="form-row">
            <text class="form-label">申请客户</text>
            <picker
              mode="selector"
              :range="clientList"
              range-key="name"
              @change="
                (e) => (addForm.clientId = clientList[e.detail.value].clientId)
              "
            >
              <view class="picker-field align-left">
                {{
                  addForm.clientId
                    ? getClientName(addForm.clientId)
                    : "请选择客户"
                }}
              </view>
            </picker>
          </view>
          <view class="form-row">
            <text class="form-label">外出事由</text>
            <input
              v-model="addForm.reason"
              placeholder="外出事由"
              class="input-field align-left"
            />
          </view>
          <view class="form-row">
            <text class="form-label">外出时间</text>
            <picker
              mode="date"
              @change="(e) => (addForm.leaveDate = e.detail.value)"
            >
              <view class="picker-field small align-left">{{
                addForm.leaveDate || "选择日期"
              }}</view>
            </picker>
            <picker
              mode="time"
              @change="(e) => (addForm.leaveTime = e.detail.value)"
            >
              <view class="picker-field small align-left">{{
                addForm.leaveTime || "选择时间"
              }}</view>
            </picker>
          </view>
          <view class="form-row">
            <text class="form-label">预计回院</text>
            <picker
              mode="date"
              @change="(e) => (addForm.expectedReturnDate = e.detail.value)"
            >
              <view class="picker-field small align-left">{{
                addForm.expectedReturnDate || "选择日期"
              }}</view>
            </picker>
            <picker
              mode="time"
              @change="(e) => (addForm.expectedReturnTime = e.detail.value)"
            >
              <view class="picker-field small align-left">{{
                addForm.expectedReturnTime || "选择时间"
              }}</view>
            </picker>
          </view>
        </view>
        <view class="dialog-btns beauty-btns">
          <button class="c-btn cancel" @click="showAddDialog = false">
            取消
          </button>
          <button class="c-btn primary" @click="submitAdd">提交</button>
        </view>
      </view>
    </view>

    <!-- 回院登记弹窗 -->
    <view v-if="showReturnDialog" class="mask">
      <view class="dialog dialog-beauty">
        <view class="dialog-title">登记回院时间</view>
        <view class="dialog-form">
          <view class="form-row">
            <text class="form-label">回院时间</text>
            <picker mode="date" @change="(e) => (returnDate = e.detail.value)">
              <view class="picker-field small align-left">{{
                returnDate || "选择日期"
              }}</view>
            </picker>
            <picker mode="time" @change="(e) => (returnTime = e.detail.value)">
              <view class="picker-field small align-left">{{
                returnTime || "选择时间"
              }}</view>
            </picker>
          </view>
        </view>
        <view class="dialog-btns beauty-btns">
          <button class="c-btn cancel" @click="showReturnDialog = false">
            取消
          </button>
          <button class="c-btn primary" @click="submitReturn">确定</button>
        </view>
      </view>
    </view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      returnDate: "",
      returnTime: "",
      searchText: "",
      filterStatus: "",
      statusTabs: [
        { label: "全部", value: "" },
        { label: "待审核", value: "待审核" },
        { label: "通过", value: "通过" },
        { label: "不通过", value: "不通过" },
      ],
      applyList: [],
      page: 1,
      size: 3,
      hasMore: true,
      loading: false,
      applyId: 5, // 用户ID可动态获取
      clientList: [],
      showAddDialog: false,
      showReturnDialog: false,
      addForm: {
        clientId: "",
        reason: "",
        leaveDate: "",
        leaveTime: "",
        expectedReturnDate: "",
        expectedReturnTime: "",
      },
      currentApply: null,
    };
  },
  computed: {
    filteredList() {
      return this.applyList;
    },
  },
  onLoad() {
    this.applyId = uni.wx.getStorageSync('userId');
    this.resetAndLoad();
  },
  onPullDownRefresh() {
    this.resetAndLoad();
  },
  onReachBottom() {
    if (this.hasMore && !this.loading) {
      this.getList();
    }
  },
  methods: {
    resetAndLoad() {
      this.applyId = uni.getStorageSync("userId");
      this.page = 1;
      this.hasMore = true;
      this.applyList = [];
      this.getList();
      this.getClients();
    },
    async getList() {
      if (!this.hasMore || this.loading) {
        uni.stopPullDownRefresh();
        return;
      }
      this.loading = true;
      try {
        const res = await uni.request({
          url: "http://localhost:9000/leaveApply/page",
          method: "GET",
          data: {
            name: this.searchText,
            approvalStatus: this.filterStatus,
            expectedReturnTime: "",
            applyId: this.applyId,
            page: this.page,
            size: this.size,
          },
        });
        let response = Array.isArray(res) ? res[1].data : res.data;
        if (parseInt(response.status) !== 200) {
          uni.showToast({ title: response.msg || "查询失败", icon: "none" });
          this.loading = false;
          this.hasMore = false;
          uni.stopPullDownRefresh();
          return;
        }
        const rawList = Array.isArray(response.data) ? response.data : [];
        const newList = rawList.map((row) => ({
          leaveId: row.leaveApply.leaveId,
          applyId: row.leaveApply.applyId,
          clientId: row.client.clientId,
          clientName: row.client.name,
          reason: row.leaveApply.reason,
          outTime: row.leaveApply.leaveTime,
          expectedReturnTime: row.leaveApply.expectedReturnTime,
          approvalStatus: row.leaveApply.approvalStatus,
          realReturnTime: row.leaveApply.actualReturnTime,
        }));

        if (this.page === 1) {
          this.applyList = newList;
        } else {
          this.applyList = this.applyList.concat(newList);
        }
        if (
          !response.data ||
          !Array.isArray(response.data) ||
          newList.length === 0 ||
          !response.total ||
          response.total === 0
        ) {
          this.hasMore = false;
        } else if (typeof response.total === "number") {
          this.hasMore = !(this.page * this.size >= response.total);
        } else {
          this.hasMore = newList.length === this.size;
        }
        this.page += 1;
      } catch (err) {
        uni.showToast({ title: "加载失败", icon: "none" });
        this.hasMore = false;
      }
      this.loading = false;
      uni.stopPullDownRefresh();
    },
    setFilter(val) {
      this.filterStatus = val;
      this.resetAndLoad();
    },
    search() {
      this.resetAndLoad();
    },
    getClients() {
      uni.request({
        url: "http://localhost:9000/client/getClientByUserId",
        method: "GET",
        data: { userId: this.applyId },
        success: (res) => {
          this.clientList = res.data.data;
        },
      });
    },
    getClientName(id) {
      const c = this.clientList.find((v) => v.clientId == id);
      return c ? c.name : "";
    },
    submitAdd() {
      const {
        clientId,
        reason,
        leaveDate,
        leaveTime,
        expectedReturnDate,
        expectedReturnTime,
      } = this.addForm;
      if (
        !clientId ||
        !reason ||
        !leaveDate ||
        !leaveTime ||
        !expectedReturnDate ||
        !expectedReturnTime
      ) {
        uni.showToast({ title: "请填写完整信息", icon: "none" });
        return;
      }
      // 拼接成带秒格式
      const leaveTimeFull = `${leaveDate} ${leaveTime}:00`;
      const expectedReturnTimeFull = `${expectedReturnDate} ${expectedReturnTime}:00`;
      const data = {
        clientId,
        reason,
        leaveTime: leaveTimeFull,
        expectedReturnTime: expectedReturnTimeFull,
        applyId: this.applyId,
      };
      uni.request({
        url: "http://localhost:9000/leaveApply/apply",
        method: "POST",
        header: {
          "content-type": "application/x-www-form-urlencoded",
        },
        data,
        success: (res) => {
          if (res.data.status === 200) {
            uni.showToast({ title: "申请已提交", icon: "success" });
            this.showAddDialog = false;
            this.resetAndLoad();
          } else {
            uni.showToast({ title: res.data.msg || "提交失败", icon: "none" });
          }
        },
      });
    },
    openReturnDialog(item) {
      this.currentApply = item;
      this.returnDate = "";
      this.returnTime = "";
      this.showReturnDialog = true;
    },
    submitReturn() {
      if (!this.returnDate || !this.returnTime) {
        uni.showToast({ title: "请选择完整时间", icon: "none" });
        return;
      }
      const datetime = `${this.returnDate} ${this.returnTime}:00`;
      uni.request({
        url: "http://localhost:9000/leaveApply/registerReturn",
        method: "POST",
        header: {
          "content-type": "application/x-www-form-urlencoded",
        },
        data: {
          leaveId: this.currentApply.leaveId,
          actualReturnTime: datetime,
        },
        success: (res) => {
          if (res.data.status === 200) {
            uni.showToast({ title: "回院登记成功", icon: "success" });
            this.showReturnDialog = false;
            this.resetAndLoad();
          } else {
            uni.showToast({ title: res.data.msg || "登记失败", icon: "none" });
          }
        },
      });
    },
    approvalText(status) {
      if (status === "待审核") return "待审核";
      if (status === "通过") return "通过";
      if (status === "不通过") return "不通过";
      return status;
    },
    quickReturn(item) {
      // 当前时间 yyyy-MM-dd HH:mm:ss
      const now = new Date();
      const pad = (n) => (n < 10 ? "0" + n : n);
      const curTime =
        now.getFullYear() +
        "-" +
        pad(now.getMonth() + 1) +
        "-" +
        pad(now.getDate()) +
        " " +
        pad(now.getHours()) +
        ":" +
        pad(now.getMinutes()) +
        ":" +
        pad(now.getSeconds());

      uni.showLoading({ title: "提交中..." });
      uni.request({
        url: "http://localhost:9000/leaveApply/registerReturn",
        method: "POST",
        header: {
          "content-type": "application/x-www-form-urlencoded",
        },
        data: {
          leaveId: item.leaveId,
          actualReturnTime: curTime,
        },
        success: (res) => {
          uni.hideLoading();
          if (res.data.status === 200) {
            uni.showToast({ title: "回院登记成功", icon: "success" });
            this.showReturnDialog = false;
            this.resetAndLoad();
          } else {
            uni.showToast({ title: res.data.msg || "登记失败", icon: "none" });
          }
        },
        fail: () => {
          uni.hideLoading();
          uni.showToast({ title: "网络错误", icon: "none" });
        },
      });
    },
  },
};
</script>

<style scoped>
/* ===== 整体背景与头部 ===== */
.out-bg {
  min-height: 100vh;
  background: #fffbe6;
  padding-bottom: 24px;
}
.top-bar {
  display: flex;
  justify-content: space-around;
  align-items: center;
  background: #fff;
  border-bottom: 1.5px solid #fae3b1;
  border-radius: 0 0 16px 16px;
  box-shadow: 0 1.5px 12px #fce9bd2c;
  margin-bottom: 6px;
}
.tab-btn {
  padding: 6px 16px;
  color: #b48709;
  font-size: 15px;
  background: none;
  border-radius: 12px;
  font-weight: 600;
  transition: background 0.18s, color 0.18s;
}
.tab-btn.active {
  color: #fff;
  background: #faad14;
}

/* ===== 查询栏 ===== */
.search-row {
  display: flex;
  align-items: center;
  padding: 0 18px;
  margin-bottom: 10px;
}
.search-input {
  flex: 1;
  height: 34px;
  border-radius: 16px;
  border: none;
  padding: 0 14px;
  background: #fff;
  font-size: 15px;
  color: #333;
  margin-right: 10px;
  box-shadow: 0 2px 7px #f9f1dd63;
  line-height: 34px;
  display: flex;
  align-items: center;
}
.search-btn,
.add-btn {
  background: #faad14;
  color: #fff;
  border: none;
  border-radius: 14px;
  height: 32px;
  padding: 0 14px;
  font-size: 15px;
  line-height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.search-btn { margin-right: 14px; }

/* ===== 卡片列表 ===== */
.apply-list {
  padding: 0 10px;
}
.apply-item {
  background: #fff;
  border-radius: 14px;
  box-shadow: 0 2px 12px #fae1b12b;
  margin-bottom: 18px;
  padding: 16px 14px 10px 14px;
  position: relative;
}
.info-row {
  display: flex;
  align-items: center;
  margin-bottom: 7px;
}
.client-name {
  font-size: 17px;
  color: #faad14;
  font-weight: 700;
  flex: 1;
}
.status-badge {
  font-size: 13px;
  border-radius: 7px;
  padding: 2px 11px;
  font-weight: bold;
  background: #eee;
  color: #b48709;
}
.status-badge.pending { background: #f9d47e; color: #b48709; }
.status-badge.approved { background: #e2ffd8; color: #18b566; }
.status-badge.rejected { background: #fef2f2; color: #eb2f2f; }
.desc-row {
  color: #666;
  font-size: 14px;
  margin: 2px 0;
}
.returned {
  color: #18b566;
  font-weight: 600;
}
.row-btns {
  width: 100%;
  margin-top: 6px;
  display: flex;
  gap: 12px;
  justify-content: space-between;
}
.normal-btn, .quick-btn, .row-btn-disabled {
  flex: 1;
  border-radius: 8px;
  font-size: 14px;
  padding: 2px 18px;
  border: none;
  font-weight: bold;
  display: flex;
  align-items: center;
  justify-content: center;
}
.normal-btn { background: #18b566; color: #fff; }
.quick-btn {
  background: linear-gradient(90deg, #1890ff 0%, #40c9fa 100%);
  color: #fff;
  box-shadow: 0 2px 10px #40c9fa33;
  transition: background 0.2s;
}
.quick-btn:active {
  background: linear-gradient(90deg, #40c9fa 0%, #1890ff 100%);
}
.row-btn-disabled { background: #dadada; color: #aaa; }

.empty-tip {
  color: #bbb;
  font-size: 15px;
  text-align: center;
  margin: 50px 0 0 0;
}

/* ===== 弹窗蒙版和内容 ===== */
.mask {
  position: fixed;
  left: 0; right: 0; top: 0; bottom: 0;
  background: #0007;
  z-index: 99;
  display: flex;
  align-items: flex-start;
  justify-content: center;
}
.dialog, .dialog-beauty {
  width: 90vw;
  max-width: 400px;
  background: #fffbe6;
  border-radius: 16px;
  padding: 15px 10px 10px 10px;
  box-shadow: 0 8px 32px #fae1b140;
  margin-top: 60px !important;
}
.dialog-title {
  font-size: 20px;
  color: #faad14;
  font-weight: bold;
  text-align: center;
  margin-bottom: 18px;
  letter-spacing: 0.5px;
}
.dialog-form {
  width: 100%;
  max-width: 400px;
  margin: 0 auto;
}

/* ======= 表单布局与输入样式 ======= */
.form-row {
  display: flex;
  align-items: center;
  width: 100%;
  margin-bottom: 16px;
  box-sizing: border-box;
  gap: 0;
}
.form-label {
  flex: 0 0 98px;
  min-width: 86px;
  max-width: 120px;
  height: 40px;
  color: #b48709;
  font-size: 18px;
  margin-right: 12px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  line-height: 1.2;
  background: transparent;
  box-sizing: border-box;
}

/* ======= 输入/选择框 ======= */
.picker-field,
.input-field {
  flex: 1 1 0;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  height: 40px;
  width: 100%;
  min-width: 0;
  box-sizing: border-box;
  margin: 0;
  padding: 0 14px;
  font-size: 14px;
  border-radius: 10px;
  background: #fff;
  border: 1.5px solid #fae1b1;
  color: #222;
  line-height: 40px;
  transition: border-color 0.15s;
  text-align: left;
}

/* 占位符样式，垂直居中，颜色变浅灰，字号统一 */
.input-field::placeholder,
.picker-field::placeholder {
  color: #bbb !important;
  font-size: 14px !important;
  opacity: 1;
  line-height: 40px;
}
.picker-field[empty] {
  color: #bbb !important;
  font-size: 14px !important;
}
.picker-field {
  color: #bbb !important;
  font-size: 14px !important;
}

/* 并排时间/日期选择短输入框 */
.picker-field.small, .input-field.small {
  min-width: 110px;
  max-width: 140px;
  font-size: 15px;
  margin-right: 0;
  padding: 0 10px;
}

/* 多输入时分栏，始终右对齐 */
.form-row > .picker-field,
.form-row > .input-field,
.form-row > picker {
  flex: 1 1 0;
  max-width: 100%;
}
.form-row > picker { margin-right: 0 !important; }
.form-row > picker:last-child { margin-right: 0 !important; }

/* ======= 按钮组 ======= */
.dialog-btns, .beauty-btns {
  display: flex;
  justify-content: space-between;
  margin-top: 12px;
  padding-top: 6px;
}
.c-btn {
  flex: 1;
  height: 44px;
  font-size: 20px;
  border-radius: 10px;
  margin: 0 7px !important;
  box-shadow: 0 2px 10px #fae1b121;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.16s, color 0.16s;
  border: none;
}
.c-btn.primary {
  background: linear-gradient(90deg, #faad14 50%, #ffe095 100%);
  color: #fff;
}
.c-btn.cancel {
  background: #f4f4f4;
  color: #b48709;
}
.c-btn:active { opacity: 0.92; }

</style>
